package com.ce.pms.customer.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;


import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.customer.model.ClientDO;
import com.ce.pms.customer.model.ClientRHouseDO;
import com.ce.pms.customer.model.IdTypeDO;
import com.ce.pms.customer.model.IndividualDO;
import com.ce.pms.customer.model.ParticipantDO;
import com.ce.pms.customer.model.ParticipantRelationDO;
import com.ce.pms.customer.model.RelationTypeDO;
import com.ce.pms.customer.service.IMemberService;
import com.ce.pms.customer.vo.MemberVO;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.house.model.HouseDomain;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.utils.base.PopulateUtil;

public class MemberServiceImpl extends CustomerServiceImpl implements
		IMemberService {

	/**
	 * 方法描述:获得成员所有关系类型
	 *
	 * @author 胡煦 Create on:2008-6-11
	 * @param
	 * @return Edit author: Edit on: 修改原因：
	 */
	public List<RelationTypeDO> getReletionType() {
		// System.out.println(relationTypeDao);
		return relationTypeDao.getRelationOfMember();
	}

	/**
	 * 方法描述: 根据户主ID列表和相应房屋ID列表找到其相应家庭成员
	 *
	 * @author 胡煦 Create on:2008-6-4
	 * @param id：户主ID
	 * @return 返回当前页的查询结果 Edit author: Edit on: 修改原因：
	 */
	public List<MemberVO> findMemberbyListId(List<Long> lid, List<Long> hid) {
		List<MemberVO> memberLists = new ArrayList<MemberVO>();
		for (Long id : lid) {
			for (Long houseid : hid) {
				Object[] o = participantRoleDao.getParticipantRoleBy(id, houseid);
				List list = memberDao.findMemberbyId((Long) o[0], houseid);
				for (int i = 0; i < list.size(); i++) {
					ClientRHouseDO clientRHouseDO = (ClientRHouseDO) list
							.get(i);
					MemberVO memberVO = convertDoToVo(clientRHouseDO, id);
					memberLists.add(memberVO);
				}
			}
		}
		return memberLists;

	}

	/**
	 * 方法描述: 根据客户查找房屋
	 *
	 * @author 胡煦 Create on:2008-6-4
	 * @param id：户主ID
	 * @return Edit author: Edit on: 修改原因：
	 */
	public List gethouseIdByClientId(Long clientId) {
		if(BlankUtil.isBlank(clientId)){
			return null;
		}
		List houseList = clientDao.getHouseIdsByClientId(clientId);
		return houseList;
	}

	/**
	 * 方法描述: 根据客户和房屋删除家庭成员
	 *
	 * @author 胡煦 Create on:2008-6-4
	 * @param id：户主ID
	 * @return Edit author: Edit on: 修改原因：
	 */
	public Long deleteMemberRel(Long ownerId, Long paticpantId,
			Long houseId) {
		List memberList = findMemberBy(ownerId, houseId);
		if (memberList != null) {
			for (int i = 0; i < memberList.size(); i++) {
				MemberVO m = (MemberVO) memberList.get(i);
				if (m.getParticipantId().equals(paticpantId)) {
					this.deleteMemberRelation(ownerId, m.getClientId(), m
							.getRelationId(), houseId);
				}
			}
		}
		return null;

	}

	/**
	 * 方法描述: 验证此客户在该房间是否已经存在相关角色
	 * @author 胡煦
	 * Create on:2008-12-9
	 * @param Long houseId, Long clientId
	 * @return void
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public void checkHasClientRHouse(Long houseId, Long participantId){
		ClientRHouseDO clientRHouseDO = clientRHouseDao
		.getClientRHouseByHouseAndParticipantId(houseId, participantId);
		if(!BlankUtil.isBlank(clientRHouseDO)){
			throw new BusinessException("customer:customer_member_hasclientinhouse_exception",
					BusinessException.WARNING);
		}

	}

	/**
	 * 方法描述: 删除选中的家庭成员
	 *
	 * @author 胡煦 Create on:2008-6-4
	 * @param id：户主ID
	 * @return Edit author: Edit on: 修改原因：
	 */
	private Long deleteMemberRelation(Long ownerId, Long clientId,
			Long relationId, Long houseId) {

		ParticipantDO participantDO = this.customerDao.findById(ownerId);
		ParticipantRelationDO participantRelationDO = participantRelationDao
				.findById(relationId);
		participantDO.getForwardRelations().remove(participantRelationDO);
		ClientRHouseDO clientRHouseDO = clientRHouseDao
				.getClientRHouseByHouseAndClient(houseId, clientId);
		ClientDO clientDO = clientDao.findById(clientId);
		clientDO.getClientRHouses().remove(clientRHouseDO);
		// clientRHouseDO.setClient(null);
		clientRHouseDao.deleteObject(clientRHouseDO);
		return participantRelationDO.getParticipantRelationId();
	}

	/**
	 * Function:vo转换为do之后对个人资料进行保存
	 *
	 * @param
	 * @return Create author:胡煦 Create on:2008-7-14 Edit author: Edit on: Why:
	 */
	private IndividualDO handleIndividual(MemberVO memberVO) {
		IndividualDO individualDO = new IndividualDO();
		PopulateUtil.populate(memberVO, individualDO);

		SysInfo sysInfo = super.createInfo(memberVO.getCreaterId());
		individualDO.setSysInfo(sysInfo);
		SysrefcodeDO sex = new SysrefcodeDO();
		sex.setId(memberVO.getSexId());
		individualDO.setSex(sex);// 性别
		IdTypeDO idType = idTypeDao.findById(memberVO.getID_typeId());
		individualDO.setIdType(idType);// 证件类型
		individualDO.setIdNumber(memberVO.getCertificateNo());// 证件号码
		individualDO.setBirthday(memberVO.getBirthday());// 出生日期
		individualDO.setHomePlace(memberVO.getHomePlace());// 籍贯

		// 新增或修改信息
		individualDO = addOrEditIndividual(individualDO);
		// 把id返回去
		memberVO.setParticipantId(individualDO.getParticipantId());

		return individualDO;
	}

	/**
	 *
	 * 功能描述: 增加或修改客户
	 *
	 * @author 胡煦 Created on:2008-7-14
	 *
	 * 修改原因：
	 * @param individualDO
	 *            参与人实体
	 * @param ownerId
	 *            户主ID
	 * @param houseId
	 *            房屋ID
	 * @param createrId
	 *            操作用户
	 *
	 * @return ClientDO 客户实体
	 */
	private ClientDO addOrEditClient(IndividualDO individualDO,
			ClientDO ownerOrlessee, Long createrId) {
		//ClientRHouseDO clientRHouseDO = new ClientRHouseDO();
		SysInfo sysInfo = createInfo(createrId);
		ClientDO clientDO = null;
		// 建立与客户DO的关系
		if (SysrefcodeDO.CLIENT_TYPE_OWNER.equals(ownerOrlessee.getClientType()
				.getValue())) {
			clientDO = clientDao.queryClientByParticipantAndClientType(
					individualDO.getParticipantId(), sysrefcodeDao
							.getSysrefCodesByCode("CS_CLIENT_CLIENT_TYPE",
									SysrefcodeDO.CLIENT_TYPE_OWNERMEMBER)
							.getId());
			if (BlankUtil.isBlank(clientDO)) {
				clientDO = new ClientDO(individualDO, sysInfo, sysrefcodeDao
						.getSysrefCodesByCode("CS_CLIENT_CLIENT_TYPE",
								SysrefcodeDO.CLIENT_TYPE_OWNERMEMBER));
			}
			//clientRHouseDO.setClient(clientDO);
			clientDO = clientDao.saveOrUpdateObject(clientDO);
		} else if (SysrefcodeDO.CLIENT_TYPE_LESSEE.equals(ownerOrlessee
				.getClientType().getValue())) {
			clientDO = clientDao.queryClientByParticipantAndClientType(
					individualDO.getParticipantId(), sysrefcodeDao
							.getSysrefCodesByCode("CS_CLIENT_CLIENT_TYPE",
									SysrefcodeDO.CLIENT_TYPE_LESSEEMEMBER)
							.getId());
			if (BlankUtil.isBlank(clientDO)) {
				clientDO = new ClientDO(individualDO, sysInfo, sysrefcodeDao
						.getSysrefCodesByCode("CS_CLIENT_CLIENT_TYPE",
								SysrefcodeDO.CLIENT_TYPE_LESSEEMEMBER));
			}
			//clientRHouseDO.setClient(clientDO);
			clientDO = clientDao.saveObject(clientDO);
		}
		return clientDO;
	}

	/**
	 * Function:保存或者更新参与人直接的关系
	 *
	 * @param
	 * @return Create author:胡煦 Create on:2008-7-12 Edit author: Edit on: Why:
	 */
	private ParticipantRelationDO addOrEditParticipantRelation(
			IndividualDO individualDO, MemberVO memberVO) {

		SysInfo sysInfo = createInfo(memberVO.getCreaterId());

		ParticipantDO participantDO = customerDao.findById(memberVO.getOwnerId());
		ParticipantRelationDO participantRelationDO = null;

		if(!BlankUtil.isBlank(memberVO.getOldParticipantId())){
			participantRelationDO = participantRelationDao
			.queryParticipantRelation(memberVO.getOwnerId(),
					memberVO.getOldParticipantId());

		}else{
			participantRelationDO = participantRelationDao
			.queryParticipantRelation(memberVO.getOwnerId(),
					individualDO.getParticipantId());
		}

		if (BlankUtil.isBlank(participantRelationDO)) {
			participantRelationDO = new ParticipantRelationDO();
			participantRelationDO.setSysInfo(sysInfo);
			participantRelationDO.setParticipant1(participantDO);
			participantRelationDO.setParticipant2(individualDO);
			participantRelationDO.setRelationType(relationTypeDao
					.findById(memberVO.getRelationTypeId()));
			participantRelationDO = participantRelationDao
					.saveObject(participantRelationDO);
		}else{
			participantRelationDO.setParticipant1(participantDO);
			participantRelationDO.setParticipant2(individualDO);
			SysInfo sysInfo1 = participantRelationDO.getSysInfo();
			super.modifyInfo(sysInfo1, memberVO.getCreaterId());
		}
		participantRelationDO.setRelationType(relationTypeDao
				.findById(memberVO.getRelationTypeId()));

		participantRelationDO = participantRelationDao
				.updateObject(participantRelationDO);

		return participantRelationDO;
	}

	/**
	 * Function:建立房间和客户之间的关系
	 *
	 * @param
	 * @return Create author:胡煦 Create on:2008-7-13 Edit author: Edit on: Why:
	 */
	private ClientRHouseDO setClientRHouse(ClientDO ownerOrlessee,ClientDO clientDO,MemberVO memberVO) {

		ClientRHouseDO clientRHouseDO = null;
		if(!BlankUtil.isBlank(memberVO.getOldHouseId())&&!BlankUtil.isBlank(memberVO.getOldParticipantId())){
			 clientRHouseDO = clientRHouseDao
			.getClientRHouseByHouseAndParticipantId(memberVO.getOldHouseId(), memberVO.getOldParticipantId());
		}else{
			//更新房间的id和客户的id，获得房间客户关系实体
			clientRHouseDO = clientRHouseDao
					.getClientRHouseByHouseAndClient(memberVO.getHouseId(), clientDO
							.getParticipantRoleId());
		}
		HouseDomain house = flatDao.findById(memberVO.getHouseId());
		// 如果实体为空，则说明房间和客户还没有建立关系，那么新增一个
		if (BlankUtil.isBlank(clientRHouseDO)) {
			clientRHouseDO = new ClientRHouseDO();
			clientRHouseDO.setClient(clientDO);
			clientRHouseDO.setHouse(house);
			clientRHouseDO.setValidity(SysInfo.VALIDITY);
			clientRHouseDO.setHouseHolder(ownerOrlessee);
			clientRHouseDao.saveObject(clientRHouseDO);
			return clientRHouseDO;
		}else {
			clientRHouseDO.setHouse(house);
			clientRHouseDO.setClient(clientDO);
			clientRHouseDO.setHouseHolder(ownerOrlessee);
			clientRHouseDao.updateObject(clientRHouseDO);
			return clientRHouseDO;
		}
	}

	/**
	 * 方法描述: 新增业主|租户|企业成员
	 *
	 * @author 胡煦 Create on:2008-6-5
	 * @param memberVO
	 * @return IndividualDO Edit author: Edit on: 修改原因：
	 */

	public IndividualDO addMember(MemberVO memberVO) {

		//验证此客户在该房间是否已经存在相关角色
		this.checkHasClientRHouse(memberVO.getHouseId(), memberVO.getParticipantId());
		// 保存个人信息
		IndividualDO individualDO1 = handleIndividual(memberVO);
		Object[] oid = participantRoleDao.getParticipantRoleBy(memberVO
				.getOwnerId(), memberVO.getHouseId());
		ClientDO ownerOrlessee = clientDao.findById((Serializable) oid[0]);
		// 增加或修改客户
		ClientDO clientDO = addOrEditClient(individualDO1, ownerOrlessee,
				memberVO.getCreaterId());
		// 建立成员和住户之间的关系
		ParticipantRelationDO participantRelationDO = addOrEditParticipantRelation(individualDO1, memberVO);
		// 建立成员与房屋的关系
		ClientRHouseDO clientRHouseDO = setClientRHouse(ownerOrlessee, clientDO, memberVO);
		return individualDO1;
	}

	/**
	 * 方法描述: 修改业主|租户|企业成员
	 *
	 * @author 胡煦 Create on:2008-6-5
	 * @param memberVO
	 * @return IndividualDO Edit author: Edit on: 修改原因：
	 */
	public IndividualDO editMember(MemberVO memberVO) {

		// 保存个人信息
		IndividualDO individualDO1 = handleIndividual(memberVO);
		// 建立成员和住户之间的关系
		ParticipantRelationDO participantRelationDO = addOrEditParticipantRelation(
				individualDO1,memberVO);
		if(!(memberVO.getOldParticipantId().equals(memberVO.getParticipantId()))||!(memberVO.getOldHouseId().equals(memberVO.getHouseId()))){

			//验证此客户在该房间是否已经存在相关角色
			this.checkHasClientRHouse(memberVO.getHouseId(), memberVO.getParticipantId());

			Object[] oid = participantRoleDao.getParticipantRoleBy(memberVO
					.getOwnerId(), memberVO.getHouseId());

			ClientDO ownerOrlessee = clientDao.findById((Serializable) oid[0]);
			// 增加或修改客户
			ClientDO clientDO = addOrEditClient(individualDO1, ownerOrlessee,
					 memberVO.getCreaterId());

			// 建立成员与房屋的关系
			ClientRHouseDO clientRHouseDO = setClientRHouse(ownerOrlessee, clientDO, memberVO);
		}

		return individualDO1;
	}
	/**
	 * 方法描述: 验证户主与成员在该房间内是否已经存在关系
	 * @author 胡煦
	 * Create on:2008-7-15
	 * @param
	 * @return
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public boolean checkMemberby2Id(Long ownerId , Long participantId , Long houseId) {
		List list = memberDao.checkMemberby2Id(ownerId, participantId, houseId);
		if(!BlankUtil.isBlank(list)){
			return true;
		}
		return false;
	}


	/**
	 * 方法描述:根据客户ID获取客户姓名
	 *
	 * @author 胡煦 Create on:2008-6-13
	 * @param nameStr：
	 * @return Edit author: Edit on: 修改原因：
	 */
	public List<ParticipantDO> getCustomerNameby(List<Long> customerIdList) {
		List<ParticipantDO> cn = new ArrayList<ParticipantDO>();
		for (Long l : customerIdList) {
			cn.add(customerDao.findById(l));
		}
		return cn;
	}

}
